package com.yonyou.gmcc.gateway.web.shiro;

import javax.servlet.Filter;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.filter.authc.AuthenticationFilter;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;

public class TokenShiroFilterFactoryBean extends ShiroFilterFactoryBean{

	private static final transient Logger log = LoggerFactory.getLogger(TokenShiroFilterFactoryBean.class);

	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (bean instanceof Filter) {
			log.debug("Found filter chain candidate filter '{}'", beanName);
			Filter filter = (Filter) bean;
			applyGlobalPropertiesIfNecessary(filter);
			getFilters().put(beanName, filter);
		} else {
			log.trace("Ignoring non-Filter bean '{}'", beanName);
		}
		return bean;
	}

	private void applySuccessUrlIfNecessary(Filter filter) {
		String successUrl = getSuccessUrl();
		if ((StringUtils.hasText(successUrl)) && (filter instanceof AuthenticationFilter)) {
			AuthenticationFilter authcFilter = (AuthenticationFilter) filter;

			String existingSuccessUrl = authcFilter.getSuccessUrl();
			if ("/".equals(existingSuccessUrl))
				authcFilter.setSuccessUrl(successUrl);
		}
	}

	private void applyUnauthorizedUrlIfNecessary(Filter filter) {
		String unauthorizedUrl = getUnauthorizedUrl();
		if ((StringUtils.hasText(unauthorizedUrl)) && (filter instanceof AuthorizationFilter)) {
			AuthorizationFilter authzFilter = (AuthorizationFilter) filter;

			String existingUnauthorizedUrl = authzFilter.getUnauthorizedUrl();
			if (existingUnauthorizedUrl == null)
				authzFilter.setUnauthorizedUrl(unauthorizedUrl);
		}
	}

	private void applyLoginUrlIfNecessary(Filter filter) {
		String loginUrl = getLoginUrl();
		if ((StringUtils.hasText(loginUrl)) && (filter instanceof AccessControlFilter)) {
			AccessControlFilter acFilter = (AccessControlFilter) filter;

			String existingLoginUrl = acFilter.getLoginUrl();
			if ("/login.jsp".equals(existingLoginUrl))
				acFilter.setLoginUrl(loginUrl);
		}
	}

	private void applyGlobalPropertiesIfNecessary(Filter filter) {
		applyLoginUrlIfNecessary(filter);
		applySuccessUrlIfNecessary(filter);
		applyUnauthorizedUrlIfNecessary(filter);
	}
}
